package cn.xxm.ff.log.common.utils;

import cn.xxm.ff.log.core.dto.CustomDesensitizeType;
import cn.xxm.ff.log.core.enums.DesensitizationTypeEnum;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author xuxiaoming005
 */
public class PropertyUtil {

    private static final String PREFIX = "log.desensitize.";
    private static final String TYPE_PREFIX = "log.desensitize.type.";
    private static final String CONFIG_PREFIX = "log.desensitize.config.";
    private static final String RETAIN_PREFIX = "log.desensitize.retain.";

    public PropertyUtil(ConfigurableEnvironment env) {

        init();

        if (env != null) {
            Iterator<PropertySource<?>> iterator = env.getPropertySources().iterator();
            while (iterator.hasNext()) {
                PropertySource<?> ps = iterator.next();
                if (ps.getSource() instanceof Properties) {
                    processProperties((Properties) ps.getSource());
                }else if (ps.getSource() instanceof Map){
                    Map<String, Object> source = (Map) ps.getSource();
                    if(null != source && source.size()>0){
                        processProperties(source);
                    }
                }
            }
        }

        System.out.println("global: " + GLOBAL_CONFIG);
    }

    // 全局配置
    private static final Map<String, String> GLOBAL_CONFIG = new HashMap<>(0);
    // 类型：字段映射表
    private static final Map<String, Set<String>> TYPE_FIELDS_MAPPING = new HashMap<>(0);
    // 生效列表
    private static final Map<String, CustomDesensitizeType> TYPE_RETAIN = new HashMap<>(0);

    public static Map getGlobalConfig() {
        return GLOBAL_CONFIG;
    }

    public static Map getTypeFieldsMapping() {
        return TYPE_FIELDS_MAPPING;
    }

    public static Map<String, CustomDesensitizeType> getTypeRetain() {
        return TYPE_RETAIN;
    }

    public static boolean isReady() {
        return (!GLOBAL_CONFIG.isEmpty()) && (!TYPE_FIELDS_MAPPING.isEmpty());
    }

    public void addGlobalConfigProperty(String k, String v) {
        GLOBAL_CONFIG.put(k, v);
    }

    public void addTypeFieldsMapping(String k, Set<String> v) {
        if (v == null) {
            return;
        }

        TYPE_FIELDS_MAPPING.put(k, v);
    }

    public void addTypeRetain(String k, CustomDesensitizeType v) {
        if (v == null) {
            return;
        }

        TYPE_RETAIN.put(k, v);
    }

    private static void init() {

        for (DesensitizationTypeEnum item: DesensitizationTypeEnum.values()) {
            CustomDesensitizeType type = new CustomDesensitizeType(
            item.getType(), item.getStartIndex(), item.getEndIndex());
            TYPE_RETAIN.put(item.getType(), type);
        }

    }


    public static void loadProperitesFromFiles(Properties properties) {
        try {
            init();

            if (properties == null) {
                return;
            }

            processProperties(properties);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private static void processProperties(Properties properties) {
        // filter properties
        List<String> keys = properties.stringPropertyNames().stream()
                .filter(c -> c.startsWith(PREFIX))
                .collect(Collectors.toList());

        for (String key: keys ) {
            String v = (String) properties.getOrDefault(key, "");
            // 处理脱敏字段类型
            doProcessProperties(key, v);
        }
    }


    private static void processProperties(Map<String,Object> hashMap) {
        for (Map.Entry<String, Object> entry : hashMap.entrySet()) {
            String key = (String) entry.getKey();
            String v =  entry.getValue() ==null ? "":entry.getValue().toString();
            doProcessProperties(key, v);
        }
    }

    private static void doProcessProperties(String key, String v) {
        // 处理脱敏字段类型
        if (StringUtils.startsWith(key, TYPE_PREFIX)) {
            Set<String> fields = Arrays.stream(v.split(","))
                    .map(c -> c.trim())
                    .collect(Collectors.toSet());
            if (!fields.isEmpty()) {
                String k = key.substring(TYPE_PREFIX.length());
                TYPE_FIELDS_MAPPING.put(k, fields);
            }
        } else if (StringUtils.startsWith(key, CONFIG_PREFIX)) {
            // 处理配置类型
            String k = key.substring(CONFIG_PREFIX.length());
            GLOBAL_CONFIG.put(k, v);
        } else if (StringUtils.startsWith(key, RETAIN_PREFIX)) {
            // 处理自动保留字�1�7�辑
            String k = key.substring(RETAIN_PREFIX.length());
            String[] indexes = StringUtils.split(v, ",");
            addRetainType(k, indexes);
        }
    }

    private static void addRetainType(String k, String[] indexes) {
        if (ArrayUtils.isEmpty(indexes)
                || indexes.length != 2) {
            return;
        }

        try {
            int startIndex = Integer.parseInt(indexes[0]);
            int endIndex = Integer.parseInt(indexes[1]);
            CustomDesensitizeType type = new CustomDesensitizeType(k, startIndex, endIndex);
            TYPE_RETAIN.put(k, type);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    //指定配置文件地址//resource目录丄1�7
        //读取.properties 结尾的配置文件用，getP, getParam
    public static Map<String,String> getP(String path) throws Exception{
        Resource resource = new ClassPathResource(path);
        Properties props = PropertiesLoaderUtils.loadProperties(resource);
        Map<String,String> param = new HashMap<String,String>((Map) props);
        return param;
    }

    public static Map<String,Set<String>> getMap(){
        Map<String,Set<String>> map2=new HashMap<String,Set<String>>();
        Map<String, String> app = null;
        try {
            app = getP("desensitization.properties");
        } catch (Exception e) {
            e.printStackTrace();
        }

        String[] key=new String[]{"cardNames","custKeyNames","phoneKeyNames","emailKeyNames","idNoKeyNames","homeAddressKeys","otherKeyNames"};
        Set<String> fields=null;
        String[] list=new String[]{app.get("cardNames"),app.get("custKeyNames"),app.get("phoneKeyNames"),app.get("emailKeyNames"),app.get("idNoKeyNames"),app.get("homeAddressKeys"),app.get("otherKeyNames")};
        String[] list2=null;
        try {

            for (int i = 0; i < key.length; i++) {
                list2=list[i].split(",");
                fields=new HashSet<>();
                for(int j=0;j<list2.length;j++){
                    fields.add(list2[j]);
                }
                map2.put(key[i],fields);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map2;

    }

    public static void main(String[] args) throws Exception {
        /*Resource resource = new FileSystemResource("D:\\Users\\wuhongtao627\\Documents\\workspace\\projects\\git\\fps-dev\\ocss-fps-server\\target\\ocss-fps-server-${env}-1.0.0.${buildNumber}.jar");

        Resource resource1 = resource.createRelative("/BOOT-INF/classes");
        System.out.println(resource1);*/
        System.out.println("abc".concat("bcd"));

    }

}

